﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace PrzetwarzanieObrazow
{
    class Filtry
    {

        ListaMetod listaMetod = new ListaMetod();
        List<Filtr> filtrList= new List<Filtr>();
        public List<Filtr> getFiltrList()
        {
            //ListaMetod.MojaMetoda metoda1 = new ListaMetod.MojaMetoda(listaMetod.zrobCzarn);
            Filtr filtr1 = new Filtr("Zrob czarny obraz", listaMetod.zrobCzarn );
            Filtr filtr2 = new Filtr("Pusty", listaMetod.nothing );
            Filtr filtr3 = new Filtr("Redukcja Szumu", listaMetod.noisereductionType1);
            Filtr filtr4 = new Filtr("Redukcja Szumu 2", listaMetod.noisereductionType2);
            Filtr filtr5 = new Filtr("Redukcja Szumu 3 ", listaMetod.noisereductionType3);
            Filtr filtr6 = new Filtr("Redukcja Szumu 4", listaMetod.noisereductionType4);
            Filtr filtr7 = new Filtr("Krawędź Laplasjan", listaMetod.edgedetectionLaplasjan1);
            Filtr filtr8 = new Filtr("Krawędź Laplasjan 2", listaMetod.edgedetectionLaplasjan2);
            Filtr filtr9 = new Filtr("Krawędź Laplasjan 3", listaMetod.edgedetectionLaplasjan3);
            Filtr filtr10 = new Filtr("Krawędź Laplasjan 4", listaMetod.edgedetectionLaplasjan4);
            Filtr filtr11 = new Filtr("Krawędź Laplasjan 5", listaMetod.edgedetectionLaplasjan5);
            Filtr filtr12 = new Filtr("Krawędź Laplasjan 6", listaMetod.edgedetectionLaplasjan6);
            Filtr filtr13 = new Filtr("Lewe Górny Rogi", listaMetod.cornerdetectionUpperLeft);
            Filtr filtr14 = new Filtr("Prawe Górne Rogi", listaMetod.cornerdetectionUpperRight);
            Filtr filtr15 = new Filtr("Lewe Dolne Rogi", listaMetod.cornerdetectionDownLeft);
            Filtr filtr16 = new Filtr("Prawe Dolne Rogi", listaMetod.cornerdetectionDownRight);
            Filtr filtr17 = new Filtr("Gradient Robertsa 45", listaMetod.gradientRoberts45);
            Filtr filtr18 = new Filtr("Gradient Robertsa 135", listaMetod.gradientRoberts135);
            Filtr filtr19 = new Filtr("Prewitt Horizontal", listaMetod.prewittHorizontal);
            Filtr filtr20 = new Filtr("Prewitt Vertical", listaMetod.prewittVertical);
            Filtr filtr21 = new Filtr("Negatyw", listaMetod.negative);
            filtrList.Add(filtr1);
            filtrList.Add(filtr2);
            filtrList.Add(filtr3);
            filtrList.Add(filtr4);
            filtrList.Add(filtr5);
            filtrList.Add(filtr6);
            filtrList.Add(filtr7);
            filtrList.Add(filtr8);
            filtrList.Add(filtr9);
            filtrList.Add(filtr10);
            filtrList.Add(filtr11);
            filtrList.Add(filtr12);
            filtrList.Add(filtr13);
            filtrList.Add(filtr14);
            filtrList.Add(filtr15);
            filtrList.Add(filtr16);
            filtrList.Add(filtr17);
            filtrList.Add(filtr18);
            filtrList.Add(filtr19);
            filtrList.Add(filtr20);
            filtrList.Add(filtr21);
            return filtrList;
        }
       
    }
    public  class ListaMetod
    {
        public delegate UnsafeBitmap MojaMetoda(UnsafeBitmap bmp1);

        public UnsafeBitmap nothing(UnsafeBitmap bmp1)
        {
            int[,] maska = new int[3, 3] { { 1, 1, 1 }, { 1, 1, 1 }, { 1, 1, 1 } };
            FiltrowanieMaska filtrowaniemaska = new FiltrowanieMaska();
            return filtrowaniemaska.przetworz(bmp1, maska, 3);
        }
        public UnsafeBitmap zrobCzarn(UnsafeBitmap bmp1)
        {
            PixelData px = new PixelData();
            px.blue = 0;
            px.green = 0;
            px.red = 0;
            
            for (int i = 0; i < bmp1.Bitmap.Width; i++)
            {
                for (int j = 0; j < bmp1.Bitmap.Height; j++)
                {

                    bmp1.SetPixel(i, j, px);
                }
            }
            return bmp1;
        }


        //Szum
        public UnsafeBitmap noisereductionType1(UnsafeBitmap bmp1)
        {
            int[,] maska = new int[3, 3] { { 1, 1, 1 }, { 1, 1, 1 }, { 1, 1, 1 } };
            FiltrowanieMaska filtrowaniemaska = new FiltrowanieMaska();
            return filtrowaniemaska.przetworz(bmp1, maska, 3);
        }
        public UnsafeBitmap noisereductionType2(UnsafeBitmap bmp1)
        {
            int[,] maska = new int[3, 3] { { 1, 2, 1 }, { 1, 2, 1 }, { 1, 1, 1 } };
            FiltrowanieMaska filtrowaniemaska = new FiltrowanieMaska();
            return filtrowaniemaska.przetworz(bmp1, maska, 3);
        }
        public UnsafeBitmap noisereductionType3(UnsafeBitmap bmp1)
        {
            int[,] maska = new int[3, 3] { { 1, 2, 1 }, { 2, 4, 2 }, { 1, 2, 1 } };
            FiltrowanieMaska filtrowaniemaska = new FiltrowanieMaska();
            return filtrowaniemaska.przetworz(bmp1, maska, 3);
        }
        public UnsafeBitmap noisereductionType4(UnsafeBitmap bmp1)
        {
            int[,] maska = new int[3, 3] { { 1, 1, 1 }, { 1, 0, 1 }, { 1, 1, 1 } };
            FiltrowanieMaska filtrowaniemaska = new FiltrowanieMaska();
            return filtrowaniemaska.przetworz(bmp1, maska, 3);
        }


        //EDGES
        public UnsafeBitmap edgedetectionLaplasjan1(UnsafeBitmap bmp1)
        {
            int[,] maska = new int[3, 3] { { 0, -1, 0 }, { -1, 4, -1 }, { 0, -1, 0 } };
            FiltrowanieMaska filtrowaniemaska = new FiltrowanieMaska();
            return filtrowaniemaska.przetworz(bmp1, maska, 3);
        }
        public UnsafeBitmap edgedetectionLaplasjan2(UnsafeBitmap bmp1)
        {
            int[,] maska = new int[3, 3] { { -1, -1, -1 }, { -1, 8, -1 }, { -1, -1, -1 } };
            FiltrowanieMaska filtrowaniemaska = new FiltrowanieMaska();
            return filtrowaniemaska.przetworz(bmp1, maska, 3);
        }
        public UnsafeBitmap edgedetectionLaplasjan3(UnsafeBitmap bmp1)
        {
            int[,] maska = new int[3, 3] { { -1, -2, -1 }, { -2, 4, -2 }, { -1, -2, -1 } };
            FiltrowanieMaska filtrowaniemaska = new FiltrowanieMaska();
            return filtrowaniemaska.przetworz(bmp1, maska, 3);
        }
        public UnsafeBitmap edgedetectionLaplasjan4(UnsafeBitmap bmp1)
        {
            int[,] maska = new int[3, 3] { { 0, -1, 0 }, { -1, 5, -1 }, { 0, -1, 0 } };
            FiltrowanieMaska filtrowaniemaska = new FiltrowanieMaska();
            return filtrowaniemaska.przetworz(bmp1, maska, 3);
        }
        public UnsafeBitmap edgedetectionLaplasjan5(UnsafeBitmap bmp1)
        {
            int[,] maska = new int[3, 3] { { -1, -1, -1 }, { -1, 9, -1 }, { -1, -1, -1 } };
            FiltrowanieMaska filtrowaniemaska = new FiltrowanieMaska();
            return filtrowaniemaska.przetworz(bmp1, maska, 3);
        }
        public UnsafeBitmap edgedetectionLaplasjan6(UnsafeBitmap bmp1)
        {
            int[,] maska = new int[3, 3] { { -1, -2, -1 }, { -2, 5, -2 }, { -1, -2, -1 } };
            FiltrowanieMaska filtrowaniemaska = new FiltrowanieMaska();
            return filtrowaniemaska.przetworz(bmp1, maska, 3);
        }

        //CORNERS
        public UnsafeBitmap cornerdetectionUpperLeft(UnsafeBitmap bmp1)
        {
            int[,] maska = new int[3, 3] { { -1, -1, 1 }, { -1, -2, 1 }, { 1, 1, 1 } };
            FiltrowanieMaska filtrowaniemaska = new FiltrowanieMaska();
            return filtrowaniemaska.przetworz(bmp1, maska, 3);
        }
        public UnsafeBitmap cornerdetectionUpperRight(UnsafeBitmap bmp1)
        {
            int[,] maska = new int[3, 3] { { 1, -1, -1 }, { 1, -2, -1 }, { 1, 1, 1 } };
            FiltrowanieMaska filtrowaniemaska = new FiltrowanieMaska();
            return filtrowaniemaska.przetworz(bmp1, maska, 3);
        }
        public UnsafeBitmap cornerdetectionDownLeft(UnsafeBitmap bmp1)
        {
            int[,] maska = new int[3, 3] { { 1, 1, 1 }, { -1, -2, 1 }, { -1, -1, 1 } };
            FiltrowanieMaska filtrowaniemaska = new FiltrowanieMaska();
            return filtrowaniemaska.przetworz(bmp1, maska, 3);
        }
        public UnsafeBitmap cornerdetectionDownRight(UnsafeBitmap bmp1)
        {
            int[,] maska = new int[3, 3] { { 1, 1, 1 }, { 1, -2, -1 }, { 1, -1, -1 } };
            FiltrowanieMaska filtrowaniemaska = new FiltrowanieMaska();
            return filtrowaniemaska.przetworz(bmp1, maska, 3);
        }


        //GRADIENTS
        public UnsafeBitmap gradientRoberts45(UnsafeBitmap bmp1)
        {
            int[,] maska = new int[3, 3] { { 0, 0, 0 }, { -1, 0, 0 }, { 0, 1, 0 } };
            FiltrowanieMaska filtrowaniemaska = new FiltrowanieMaska();
            return filtrowaniemaska.przetworz(bmp1, maska, 3);
        }
        public UnsafeBitmap gradientRoberts135(UnsafeBitmap bmp1)
        {
            int[,] maska = new int[3, 3] { { 0, 0, 0 }, { 0, 0, -1 }, { 0, 1, 0 } };
            FiltrowanieMaska filtrowaniemaska = new FiltrowanieMaska();
            return filtrowaniemaska.przetworz(bmp1, maska, 3);
        }


        //PREWITT
        public UnsafeBitmap prewittHorizontal(UnsafeBitmap bmp1)
        {
            int[,] maska = new int[3, 3] { { -1, -1, -1 }, { 0, 0, 0 }, { 1, 1, 1 } };
            FiltrowanieMaska filtrowaniemaska = new FiltrowanieMaska();
            return filtrowaniemaska.przetworz(bmp1, maska, 3);
        }
        public UnsafeBitmap prewittVertical(UnsafeBitmap bmp1)
        {
            int[,] maska = new int[3, 3] { { -1, 0, 1 }, { -1, 0, 1 }, { -1, 0, 1 } };
            FiltrowanieMaska filtrowaniemaska = new FiltrowanieMaska();
            return filtrowaniemaska.przetworz(bmp1, maska, 3);
        }


        //Filtry inne
        public UnsafeBitmap negative(UnsafeBitmap bmp1)
        {
            int colr;
            int colg;
            int colb;
            for (int i = 0; i < bmp1.Bitmap.Width; i++)
            {
                for (int j = 0; j < bmp1.Bitmap.Height; j++)
                {
                    colr = 255 - bmp1.GetPixel(i,j).red;
                    colg = 255 - bmp1.GetPixel(i,j).green;
                    colb = 255 - bmp1.GetPixel(i,j).blue;
                    PixelData px = new PixelData();
                    px.red = (byte)colr;
                    px.green = (byte)colg;
                    px.blue = (byte)colb;
                    bmp1.SetPixel(i, j, px);
                }
            }
            return bmp1;
        }
    }

    class Filtr
    {
        string nazwa;
        ListaMetod listaMetod = new ListaMetod();
        ListaMetod.MojaMetoda metoda1;
        public Filtr(string name, ListaMetod.MojaMetoda mj)
        {
            metoda1 = mj;
            nazwa=name;
        }
        public UnsafeBitmap oblicz(UnsafeBitmap bm)
        {

            return metoda1(bm);
        }
        public override string  ToString()
        {
 	        return nazwa;    
        }
    }
}
